home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / BFILE.ZIP / BFILE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-11  |  7.9 KB  |  378 lines

  1. /*
  2.  
  3.       bfile.cpp
  4.       Btrieve class for Borland C++
  5.       09/06/91
  6.  
  7.       Douglas J. Reilly
  8.       Access Microsystems Inc.
  9.       404 Midstreams Road
  10.       Brick, New Jersey  08724
  11.       (908) 892-2683
  12.       CompuServe 74040,607
  13.  
  14.       Comments?  Questions?  Suggestions?
  15.       Have a paying C/C++ programming job you need done?
  16.       Give me a call.
  17.  
  18.       Released into the public domain.  Do with it as you see fit, but
  19.       if you do anything really neat with it, let me know...
  20.  
  21. 11/11/91  DR  Lots of little changes to better handle variable length
  22.                  records.
  23. */
  24. #define EOS '\0'
  25.  
  26. #include "stdio.h"
  27. #include "stdlib.h"
  28. #include "mem.h"
  29. #include "string.h"
  30. #include "ctype.h"
  31. #include "bfile.h"    // class description for bfile
  32.  
  33. class bfile;
  34. // #define this, link it with the TURBCBTR module and see an example.
  35. //    USAGE: bfile /f:filename.ext /k:key_num
  36. //#define TEST
  37. #ifdef TEST
  38. main(int argc,char *argv[])
  39. {
  40.    char temp[100];
  41.    int  ret;
  42.    int  loop;
  43.    static char file[70]={""};
  44.    int key=-1;
  45.    temp[0]='\0';
  46.  
  47.    memset(temp,'\0',100);
  48.  
  49.    for ( loop=1 ; loop<argc ; loop++ )
  50.    {
  51.       if ( argv[loop][0]=='/' )
  52.       {
  53.          switch ( (toupper(argv[loop][1])) )
  54.          {
  55.             case 'K':
  56.                key=atoi(&argv[loop][3]);
  57.                break;
  58.             case 'F':
  59.                strcpy(file,&argv[loop][3]);
  60.                break;
  61.          }
  62.       }
  63.    }
  64.  
  65.  
  66.    bfile sum(file,4096,"(C)SMI",0);
  67.    sum.set_key_num(key);
  68.  
  69.    printf("\nsum.get_rec(temp,B_GET_LO)=%d data=%30.30s temp=|%s|",
  70.                                            sum.get_rec(temp,B_GET_LO),
  71.                                            sum.get_data(),temp);
  72.    do {
  73.       printf("\nsum.get_rec(temp,B_GET_NEXT)=%d data=%30.30s temp=|%s|",
  74.                                            ret=sum.get_rec(temp,B_GET_NEXT),
  75.                                            sum.get_data(),temp);
  76.    } while ( ret==0 );
  77. }
  78. #endif
  79.  
  80. bfile::bfile(char *name,int len,char *towner,int newmode)
  81. {
  82.    int tlen=0;
  83.  
  84.    key_num=0;
  85.    opened=0;
  86.    data=0;
  87.    strcpy(fname,name);
  88.    mode=newmode;
  89.    if ( towner!=0 )
  90.    {
  91.       strcpy(data,towner);
  92.       strcpy(owner,towner);
  93.       tlen=(strlen(towner))+1;
  94.    }
  95.    else
  96.    {
  97.       tlen=len;
  98.    }
  99.    status=BTRV(B_OPEN,pos_blk,data,&tlen,fname,mode);
  100.    if ( status && status!=BERR_REC_BUF_ERR )
  101.    {
  102. //      printf("\nOpen failed for %s-status %d",fname,status);
  103.    }
  104.    else
  105.    {
  106.       opened=1;
  107.      // DECLARATION!
  108.       struct FIL_SPEC fil_spec;
  109.       get_bstat(&fil_spec);
  110.       file_flag=fil_spec.FILE_FLAG;
  111.       if ( len )
  112.       {
  113.          rec_len=len;
  114.         // get the fixed len from the FIL_SPEC
  115.          fixed_len=fil_spec.REC_LEN;
  116.       }
  117.       else
  118.       {
  119.          if ( file_flag&1 )  // variable len?
  120.          {
  121.             rec_len=5000;             // assume 5000, what the heck...
  122.          }
  123.          else
  124.          {
  125.             rec_len=fil_spec.REC_LEN;
  126.          }
  127.          fixed_len=fil_spec.REC_LEN;
  128.       }
  129.       last_rec_len=0;
  130.       num_keys=fil_spec.NDX_CNT;
  131.       data=new char[rec_len];
  132.       if ( data==0 )
  133.       {
  134.          close();
  135.          opened=0;
  136.          status=BERR_MEM_ALLOC;
  137.       }
  138.    }
  139. }
  140. bfile::~bfile()
  141. {
  142.    if ( !(opened) )
  143.    {
  144.       return;
  145.    }
  146.    else
  147.    {
  148.       status=BTRV(B_CLOSE,pos_blk,data,&rec_len,fname,mode);
  149.       delete data;
  150.       data=0;
  151.       opened=0;
  152.    }
  153. }
  154.  
  155. int bfile::close()
  156. {
  157.    if ( data!=0 )
  158.    {
  159.       delete data;
  160.       data=0;
  161.    }
  162.    if ( !(opened) )
  163.    {
  164.       return 0;
  165.    }
  166.    else
  167.    {
  168.       status=BTRV(B_CLOSE,pos_blk,data,&rec_len,fname,mode);
  169.       opened=0;
  170.       return 1;
  171.    }
  172. }
  173.  
  174. int bfile::open(int newmode)
  175. {
  176.    if ( opened )
  177.    {
  178.       return 0;
  179.    }
  180.    if ( newmode!=-99 )
  181.    {
  182.       mode=newmode;
  183.    }
  184.    opened=0;
  185.    data=new char[rec_len];
  186.    if ( data==0 )
  187.    {
  188. //      printf("\nOpen failed for %s-No memory",fname);
  189.       status=BERR_MEM_ALLOC;
  190.    }
  191.    if ( owner!=0 )
  192.    {
  193.       strcpy(data,owner);
  194.    }
  195.    status=BTRV(B_OPEN,pos_blk,data,&rec_len,fname,mode);
  196.    if ( status )
  197.    {
  198.       delete data;
  199.       data=0;
  200.    }
  201.    else
  202.    {
  203.       opened=1;
  204.    }
  205.    return(status);
  206. }
  207.  
  208. int bfile::get_rec(char *keystr,int op)
  209. {
  210.    int tlen;
  211.    if ( !(opened) || data==0 )
  212.    {
  213.       return(BERR_NO_OPEN);    // btrieve status for not opened...
  214.    }
  215.    tlen=rec_len;
  216.    memset(data,EOS,rec_len);
  217.    status=BTRV(op,pos_blk,data,&tlen,keystr,key_num);
  218.    last_rec_len=tlen;
  219.    return(status);
  220. }
  221.  
  222. int bfile::put_rec(char *keystr,int tlen)
  223. {
  224.    char *tdata;
  225.    char tkey[128];
  226.    int  stat;
  227.  
  228.    tdata=new char[rec_len];
  229.    memcpy(tdata,data,rec_len);
  230.    memcpy(tkey,keystr,128);
  231.  
  232.   // This is how I save btrieve data.  I understand that there is some
  233.   //   potential for problem with this, since by always re-establishing
  234.   //   positioning, I won't know if someone changed the data since I last
  235.   //   got the rec, but in things I have done, I lock the records first
  236.   //   anyway...
  237.  
  238.    if ( (stat=get_rec(keystr))!=0 )
  239.    {
  240.       if ( stat!=BERR_REC_NOT_FOUND && stat!=BERR_EOF )
  241.       {
  242.          delete tdata;
  243.          return(stat);
  244.       }
  245.      // new record?
  246.       if ( tlen==0 )
  247.       {
  248.          tlen=rec_len;
  249.       }
  250.       status=BTRV(B_INSERT,pos_blk,tdata,&tlen,tkey,key_num);
  251.       last_rec_len=tlen;
  252.    }
  253.    else
  254.    {
  255.       if ( tlen==0 )
  256.       {
  257.          tlen=rec_len;
  258.       }
  259.       status=BTRV(B_UPDATE,pos_blk,tdata,&tlen,tkey,key_num);
  260.       last_rec_len=tlen;
  261.    }
  262.    if ( !(status) )
  263.    {
  264.       memcpy(data,tdata,rec_len);
  265.       strcpy(keystr,tkey);
  266.    }
  267.    delete tdata;
  268.    return status;
  269. }
  270.  
  271. int bfile::del_rec(char *keystr)
  272. {
  273.    char *tdata;
  274.    char tkey[128];
  275.    int  stat;
  276.  
  277.   // use tdata so as not to destroy infor in data...
  278.    tdata=new char[rec_len];
  279.    memcpy(tdata,data,rec_len);
  280.    memcpy(tkey,keystr,128);
  281.    if ( (stat=get_rec(keystr))!=0 )
  282.    {
  283.       delete tdata;
  284.       return(stat);
  285.    }
  286.    else
  287.    {
  288.       status=BTRV(B_DELETE,pos_blk,tdata,&rec_len,tkey,key_num);
  289.    }
  290.    if ( !(status) )
  291.    {
  292.       memcpy(data,tdata,rec_len);
  293.       strcpy(keystr,tkey);
  294.    }
  295.    delete tdata;
  296.    return status;
  297. }
  298.  
  299. void bfile::get_bstat(struct FIL_SPEC *fil_spec)
  300. {
  301.    int tlen=(sizeof(struct FIL_SPEC));
  302.    char temp[60];  // S/B big enough to hold extension file name if
  303.                    //   name is returned.
  304.    status=BTRV(B_STAT,pos_blk,(char *)fil_spec,&tlen,temp,mode);
  305.    if ( status==22 )
  306.    {
  307.       status=0;
  308.    }
  309. }
  310. int  bfile::set_pos(char *buf,char *keystr)
  311.    {
  312.       int tlen=rec_len;
  313.       char temp[256];
  314.       memcpy(data,buf,4);
  315.       status=BTRV(B_GET_DIRECT,pos_blk,data,&tlen,temp,key_num);
  316.       if ( keystr )
  317.       {
  318.          strcpy(keystr,temp);
  319.       }
  320.       return(status);
  321.    }
  322.  
  323. int bfile::clone_file(char *destfname,int overwrite)
  324. {
  325.    struct FIL_SPEC fil_spec;
  326.    int tlen=(sizeof(struct FIL_SPEC));
  327.    char new_pos[128];
  328.    int newstat;
  329.    int tkey;
  330.  
  331.    if ( overwrite )
  332.    {
  333.       tkey=0;
  334.    }
  335.    else
  336.    {
  337.       tkey=-1;
  338.    }
  339.    get_bstat(&fil_spec);
  340.    if ( !(get_status()) )
  341.    {
  342.       newstat=BTRV(B_CREATE,new_pos,(char *)&fil_spec,&tlen,destfname,tkey);
  343.    }
  344.    else
  345.    {
  346.       newstat=get_status();
  347.    }
  348.    return(newstat);
  349. }
  350.  
  351. int  bfile::get_key_len(int tkey_num)
  352. {
  353.    struct FIL_SPEC fil_spec;
  354.    int key_loop;
  355.    int key_len=0;
  356.    if ( tkey_num==-1 )
  357.    {
  358.       tkey_num=key_num;
  359.    }
  360.    get_bstat(&fil_spec);
  361.    int loop;
  362.    for ( loop=0,key_loop=0 ; key_loop<tkey_num && loop<24 ; loop++ )
  363.    {
  364.       if ( !(fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // last seg?
  365.       {
  366.          key_loop++;
  367.       }
  368.    }
  369.    while ( loop<24 &&
  370.            (fil_spec.KEY_BUF[loop].KEY_FLAG&16) ) // another seg?
  371.    {
  372.       key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
  373.       loop++;
  374.    }
  375.    key_len+=fil_spec.KEY_BUF[loop].KEY_LEN;
  376.    return(key_len);
  377. }
  378.